﻿namespace Reviewer.Web.UI
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.Serialization;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Reviewer.Business;
    using Reviewer.Entities;
    using Reviewer.Entities.MetadataInfo;
    using Reviewer.Entities.Services;

    /// <summary>
    /// Summary description for MetadataItemEditPanel
    /// </summary>
    public class MetadataItemEditPanel<T> : Panel, INamingContainer where T : class, IMetadataType, new()
    {
        private List<PropertyInfo> properties;
        protected HiddenField ItemId = new HiddenField();
        protected T item;

        public MetadataItemEditPanel()
            : base()
        {
            Type tType = typeof(T);

            this.properties = new List<PropertyInfo>(tType.GetProperties())
                .Where(t => Attribute.GetCustomAttribute(t, typeof(MetadataPropertyBaseAttribute)) != null)
                .OrderBy(t => (Attribute.GetCustomAttribute(t, typeof(DataMemberAttribute)) as DataMemberAttribute).Order)
                .ToList();
        }

        public string ValidationGroup { get; set; }

        public T Save()
        {
            EnsureChildControls();

            IMetadataService<T> service = ServiceFactory.GetMetadataService<T>();

            if (this.item == null)
            {
                if (!String.IsNullOrEmpty(this.ItemId.Value))
                {
                    int itemId = int.Parse(this.ItemId.Value);
                    this.item = service.Get(itemId);
                }

                if (this.item == null)
                    this.item = new T();
            }

            foreach (Control control in this.Controls)
            {
                MetadataPropertyControl propertyControl = control as MetadataPropertyControl;
                if (propertyControl != null)
                {
                    propertyControl.SetProperty(this.item);
                }
            }

            this.item = service.Save(this.item);
            this.ItemId.Value = this.item.Id.ToString();
            return this.item;
        }

        public void Reset()
        {
            EnsureChildControls();

            this.ItemId.Value = String.Empty;

            foreach (Control ctrl in this.Controls)
            {
                var o = ctrl as MetadataPropertyControl;
                if (o != null)
                {
                    o.Reset();
                }
            }
        }

        public bool LoadItem(int id)
        {
            EnsureChildControls();

            IMetadataService<T> service = ServiceFactory.GetMetadataService<T>();

            T loadedItem = service.Get(id);
            if (loadedItem != null)
            {
                this.item = loadedItem;
                this.ItemId.Value = this.item.Id.ToString();

                foreach (Control ctrl in this.Controls)
                {
                    var o = ctrl as MetadataPropertyControl;
                    if (o != null)
                    {
                        o.GetProperty(item);
                    }
                }

                return true;
            }

            return false;
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            this.Controls.Add(ItemId);

            foreach (PropertyInfo property in this.properties)
            {
                if (property.Name.Equals("Id"))
                {
                    continue;
                }

                MetadataPropertyBaseAttribute metadataAttribute = Attribute.GetCustomAttribute(property, typeof(MetadataPropertyBaseAttribute)) as MetadataPropertyBaseAttribute;
                WebControl control = null;
                if (metadataAttribute is MetadataTextPropertyAttribute)
                {
                    if ((metadataAttribute as MetadataTextPropertyAttribute).MaxLength < 0)
                    {
                        control = new MetadataHtmlTextPropertyControl(property);
                    }
                    else
                    {
                        control = new MetadataTextPropertyControl(property);
                    }
                }
                else if (metadataAttribute is MetadataLookupPropertyAttribute)
                {
                    control = new MetadataDropDownPropertyControl(property);
                }
                else if (metadataAttribute is MetadataImagePropertyAttribute)
                {
                    control = new MetadataImagePropertyControl(property);
                }

                if (control != null)
                {
                    control.ID = (this.ID ?? this.Parent.ID) + "C" + (this.Controls.Count + 1).ToString();
                    control.GetType().GetProperty("ValidationGroup").SetValue(control, this.ValidationGroup, null);
                    this.Controls.Add(control);
                }
            }
        }
    }
}